-- Initiate Ace3 with the modules we need.
CPloot = LibStub("AceAddon-3.0"):NewAddon("CPloot", "AceConsole-3.0", "AceTimer-3.0", "AceEvent-3.0", "AceHook-3.0")
local AceConfig = LibStub("AceConfig-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")

-- LDB enable addon for TitanPanel/Fubar button to launch config window
LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("CPloot", {
	type = "launcher",
	icon = "Interface\\Icons\\inv_misc_cutgemnormal",
	OnClick = function(clickedframe, button)
		CPloot:OpenConfig()
	end,
	OnTooltipShow = function(CPlootTooltip)
		CPlootTooltip:AddLine("CPloot")
		CPlootTooltip:AddLine("Click to open CPloot options")
	end,
})

local CPloot_State = {}
local CPlootFrames = {}
local CPlootPoints = {}
local CPlootPointsLookup = {}
CPlootWonList = {} -- DEBUG should be local
local ConfigOpts
CPlootRuntime = {
	FoundItems = {
		[999] = "None",
	},								-- Stores the won items from the lookup on PlayerNameItemLookup = {}				
	FoundItemId = 999,				-- Used to store the items Id for the gui dropdown of who has also rolled on this item.
	ItemOwnerslist = {},			-- Holds those that has won one or more items for the gui move item function.
	PlayerNameItemLookup = "Fubar",	-- Used to store the players name who's won items is being looked up.
	FoundItemRollers = {
		[999] = "None",
	},								-- Store the rollers that was located from FoundItemId
	ChosenItemRoller = 999,			-- Used to store the player who should have the item moved to him or her.
	ShowNonRollers = false,			-- MoveItem .. If true will add all raid members to select player to transfer item to dropdown.
	MoveRollType = false,			-- If true will for a change of the item roll type (main/off spec) when moving it to another player.
	VersionMajor = "3",				-- Addon Major Version number. This is bumped when incompability with older versions are broken.
	VersionMinor = "01",			-- Addon Minor Version number. This is bumped for new versions that is still combatible with the previous version.
	VersionCheck = nil,				-- Keep track if user has been warned of an out of date addon.
	RollStatus = "Stopped", 		-- Used to keep track of running rolls
	RollType = nil, 				-- Keep track of current roll type
	RollLoot = {}, 					-- This is where the content of the current roll loot is stored
	SyncAwarded = false,			-- If an item has been handed out, sync CPlootAwardedItems if this is true.
	InSync = false,					-- This will prevent people from resetting Winnerlist if they are in sync.
	Loot = {}, 						-- This is where the content of the loot from the blizz window is stored
	Nuker = nil,               		-- Name of the raid nuker.
	IsInRaid = nil,					-- Keep track to see if we are already in a raid group.
	AddonVersions = nil,			-- Holds the raids addon versions to be displayed in gui
	AddonVersionsArray = {},		-- Holds the raw addon version data from players.
	LocalSetupButtonPressed = nil,	-- This is true if this player pressed the setup button
	LastVersionCheck = 0,			-- This contains the last time addon requested a version.
	AutoLootTimer = nil,			-- This is used to store the autoloot timer.
	MLCandidates = {},				-- Stores those who runs the addon.
--	DoaLootRunning = nil,			-- Make sure we don't spam constantly if DoaLoot is loaded. nil or 1
	FirstConfigFrameCall = true, -- Ensures double call to InterfaceOptionsFrame_OpenToCategory on first config frame to battle Blizzard bug
	Debug = {
		WinnerList = nil,			-- if true will print Winnerlist debug
		MasterLoot = nil,			-- If true enables MasterLoot candidate debug
		LootQuality = 3, 			-- What quality should an item have to be shown.
		MasterLootCandidates = {}, 	-- Used to store MasterLootCandidates in for debug purpose
		DebuggerName = nil,			-- Stores the name of the debugger to transmit data to
		DebugData = nil,			-- if set true, the com debug will dump the data part too
		BypassRaid = nil,			-- If true bypass raid restrictions.	
		PrintFunctionCalls = true  -- if true will print function calls that implement printing on debug
	},
}

-- This has to be after the initital creation of CPlootRuntime, as I am using variables from itself.
CPlootRuntime["DownloadURL"] = "http://CPloot.xpoints.dk/download/FastLoot_" .. CPlootRuntime["VersionMajor"] .. "." .. CPlootRuntime["VersionMinor"] .. ".zip"

CPlootCurrentRolls = {}   	-- Used to store rolls for mainspec
CPlootLists = {
	{
		["Slot"] = "None",
		["Min"] = "0",
		["Max"] = "0",
		["List"] = "Mount",
		["Persistent"] = "true",
		["EquipSlot"] = { "None" },
	},
	{
		["Slot"] = "None",
		["Min"] = "665",
		["Max"] = "695",
		["List"] = "Tier16",
		["Persistent"] = "true",
		["EquipSlot"] = { "None" },
	},
	{
		["Slot"] = "None",
		["Min"] = "0",
		["Max"] = "0",
		["List"] = "Armor",
		["Persistent"] = "true",
		["EquipSlot"] = { "LEGS", "HEAD", "NECK", "SHOULDER", "CLOAK", "CHEST", "WRIST", "HAND", "WAIST", "FEET", "FINGER", "ROBE" },
	},
	{
		["Slot"] = "None",
		["Min"] = "0",
		["Max"] = "0",
		["List"] = "Weapon",
		["Persistent"] = "true",
		["EquipSlot"] = { "2HWEAPON", "WEAPON", "SHIELD", "TRINKET", "WEAPONMAINHAND", "WEAPONOFFHAND", "RANGED", "RANGEDRIGHT", "HOLDABLE", "THROWN", "RELIC" },
	},
}

if (not CPlootAwardedItems) then
	CPlootAwardedItems = {}	-- Used to store awarded items in case some one wants to pass later.
end

if (not CPlootWonList) then
	CPlootWonList = {}
end

-- TODO might not be needed as we do not sync to website
if (not CPlootRaidRoster ) then	-- Stores raid session data for upload.
	CPlootRaidRoster = {
		Raiders = {},
		Bosses = {},
	}
end

if (not CPlootAccounts ) then
	CPlootAccounts = {}			-- Hold mains and alts. 
end

-- TODO might not be needed as we do not sync to website?
if (not CPlootGuildRoster ) then
	CPlootGuildRoster = {}			-- Holds a total update of the guild roster name, rank
end


CPloot_ConfigDb = {
	Enabled = true,   										-- Addon enabled or disabled can be true / false
	OfficialMode = true,  									-- can be Official / Unofficial
	WinnerListResetDate = date("%d/%m/%y %H:%M"),			-- Contains the date for the last lootlist reset
	Mode = nil,												-- No longer used
	MasterLooter = false,									-- Contains the default masterlooter
	RaidLootQuality = 3,					-- Set the Raids loot quality to this.
	RaidDifficulty = 3,						-- 3 = 10 player, 4 = 25 player, 5 = 10 player heroic, 6 = 25 player heroic. 
	RaidDifficultyAI = false,				-- can be true or false, will try and determine if it's a 10 or 25 man raid.
	RaidDiffucltyHeroic = false,			-- AI force heroic false / true
	RaiderRanks = {							-- If true, that guild rank is considered a raider rank.
		[0] = true,
		[1] = true,
		[2] = true,
		[3] = true,
		[4] = true,
		[5] = true,
		[6] = true,
		[7] = false,
		[8] = false,
		[9] = false,
	},
	RankNames = {
		[0] = "Rank 0",
		[1] = "Rank 1",
		[2] = "Rank 2",
		[3] = "Rank 3",
		[4] = "Rank 4",
		[5] = "Rank 5",
		[6] = "Rank 6",
		[7] = "Rank 7",
		[8] = "Rank 8",
		[9] = "Rank 9",
	},
}


--------------------------------------------------------
----  Stuff that should be done before the addon    ----
----  is enabled                                    ----
--------------------------------------------------------
function CPloot:OnInitialize()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:OnInitialize() function called") end
	self:RegisterEvent("LOOT_OPENED","GatherLootData")
	self:RegisterEvent("LOOT_CLOSED","CloseLootFrame")
	self:RegisterEvent("CHAT_MSG_SYSTEM", "IncomingRolls")
	self:RegisterEvent("VARIABLES_LOADED", "CleanOldConfig")
	self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "SetZoneName")
	self:RegisterEvent("GROUP_ROSTER_UPDATE", "RaidGroupChanged")
	self:RegisterEvent("PLAYER_ENTERING_WORLD", "EnterWorld")
	CPloot:CleanOldConfig()
	CPlootGui = CPloot:NewCPlootGui()
	ConfigOpts = CPlootGui:CreateGui()
	AceConfig:RegisterOptionsTable("CPloot", ConfigOpts, {"CPloot", "CPloot"})
	self.OptionsFrame = AceConfigDialog:AddToBlizOptions("CPloot", "CPloot")
	CPlootFrames = CPloot:NewCPlootFrames()
	CPlootPoints = CPloot:NewCPlootPoints()
	CPlootFrames:OnInitialize()  -- Initialize the CPlootFrames 
	CPlootPoints:OnInitialize()  -- Initialize the CPlootPoints module
end


--------------------------------------------------------
----     Player entering world or changing zone		----
--------------------------------------------------------
function CPloot:EnterWorld()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:EnterWorld() function called") end
	GuildRoster()
end


------------------------------------------------------------------
---- TEST CODE - enabling direct calls to modules from WowLua ----
------------------------------------------------------------------

function CPloot:GetPointsFromString(pointString) return CPlootPoints:GetPointsFromString(pointString) end

function CPloot:CreatePointString(Part1WeaponMS,Part2WeaponOS,Part3ArmorMS,Part4ArmorOS,Part5TierMS,Part6TierOS,Part7Mount,Part8LastPayed,Part9NextToLastPayed) return CPlootPoints:CreatePointString(Part1WeaponMS,Part2WeaponOS,Part3ArmorMS,Part4ArmorOS,Part5TierMS,Part6TierOS,Part7Mount,Part8LastPayed,Part9NextToLastPayed) end

--------------------------------------------------------
----     Build the loots list from CPlootLists		----
--------------------------------------------------------
-- TODO
function CPloot:GenerateCPlootWonList(Clear)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GenerateCPlootWonList() function called") end
	for Index=1, #CPlootLists do

		if ( CPlootWonList[CPlootLists[Index]["List"]] == nil ) then
			CPlootWonList[CPlootLists[Index]["List"]] = {}
			CPlootWonList[CPlootLists[Index]["List"]]["MainSpec"] = {}
			CPlootWonList[CPlootLists[Index]["List"]]["OffSpec"] = {}
		end

		if ( CPlootLists[Index]["Persistent"] == "false" or Clear == "true" ) then
			CPlootWonList[CPlootLists[Index]["List"]] = {}
			CPlootWonList[CPlootLists[Index]["List"]]["MainSpec"] = {}
			CPlootWonList[CPlootLists[Index]["List"]]["OffSpec"] = {}
		end

	end

end


--------------------------------------------------------
----     Change old saved lua, to new format		----
--------------------------------------------------------
function CPloot:CleanOldConfig()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CleanOldConfig() function called") end
	CPloot_ConfigDb["Mode"] = nil

	if not (CPloot_ConfigDb["OfficialMode"] == true or CPloot_ConfigDb["OfficialMode"] == false) then
		CPloot_ConfigDb["OfficialMode"] = true
	end

	if not (CPloot_ConfigDb["RaidLootQuality"] ) then
		CPloot_ConfigDb["RaidLootQuality"] = 3
	end

	if not (CPloot_ConfigDb["RaidDifficulty"] ) then
		CPloot_ConfigDb["RaidDifficulty"] = 3
	end

	if not (CPloot_ConfigDb["RaidDifficultyAI"] == true or CPloot_ConfigDb["RaidDifficultyAI"] == false ) then
		CPloot_ConfigDb["RaidDifficultyAI"] = true
	end

	if not (CPloot_ConfigDb["RaidDiffucltyHeroic"] == true or CPloot_ConfigDb["RaidDiffucltyHeroic"] == false  ) then
		CPloot_ConfigDb["RaidDiffucltyHeroic"] = false
	end

	if not (CPloot_ConfigDb["MasterLooter"] ) then
		CPloot_ConfigDb["MasterLooter"] = ""
	end

	if (CPloot_ConfigDb["StoreAttendence"] == false or CPloot_ConfigDb["StoreAttendence"] == true ) then
		CPloot_ConfigDb["StoreAttendence"] = nil
	end

	if not (CPlootRuntime["InSync"] == true or CPlootRuntime["InSync"] == false) then
		CPlootRuntime["InSync"] = false
	end

	if not (CPloot_ConfigDb["RaiderRanks"] ) then
		CPloot_ConfigDb["RaiderRanks"] = {
			[0] = true,
			[1] = true,
			[2] = true,
			[3] = true,
			[4] = true,
			[5] = true,
			[6] = true,
			[7] = false,
			[8] = false,
			[9] = false,
		}
	end

	if not (CPloot_ConfigDb["RankNames"]) then
		CPloot_ConfigDb["RankNames"] = {
			[0] = "Rank 0",
			[1] = "Rank 1",
			[2] = "Rank 2",
			[3] = "Rank 3",
			[4] = "Rank 4",
			[5] = "Rank 5",
			[6] = "Rank 6",
			[7] = "Rank 7",
			[8] = "Rank 8",
			[9] = "Rank 9",
		}
	end

end

--------------------------------------------------------
----             Set Raider Ranks               ----
--------------------------------------------------------
function CPloot:SetRaiderRank(RankIndex, Value)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetRaiderRank(RankIndex, Value) function called") end
	local ML = CPloot:GetML()
	local RL = CPloot:GetRL()
	-- Make sure only ML and RL can change raider ranks during a raid.
	if ( UnitInRaid("player") ) then
		if not ( UnitName("player") == ML or UnitName("player") == RL ) then
			CPloot:Print("Only Raid leader or Master looter is allowed to change loot ranks during a raid")
			return
		end
	end

	CPloot_ConfigDb["RaiderRanks"][RankIndex] = Value

end

--------------------------------------------------------
----             Get Guild Rank Names               ----
--------------------------------------------------------
function CPloot:GetGuildRanks()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetGuildRanks() function called") end
	local RankNames = {}
	RankNames = {
		[0] = "Rank 0",
		[1] = "Rank 1",
		[2] = "Rank 2",
		[3] = "Rank 3",
		[4] = "Rank 4",
		[5] = "Rank 5",
		[6] = "Rank 6",
		[7] = "Rank 7",
		[8] = "Rank 8",
		[9] = "Rank 9",
		}

	for i=1, GuildControlGetNumRanks(), 1 do
		local Rank = GuildControlGetRankName(i)
                local Index = i - 1
		RankNames[Index] = Rank
	end

	local GuildName = GetGuildInfo("player")
	if (GuildName) then
		CPloot_ConfigDb["RankNames"] = RankNames
	end

end

--------------------------------------------------------
----          Return the opposite rolltype          ----
--------------------------------------------------------
function CPloot:GetMoveRollType()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetMoveRollType() function called") end
	if (CPlootRuntime.FoundItemId ~= 999) then
		if (CPlootAwardedItems[CPlootRuntime.FoundItemId]["RollType"] == "MainSpec" ) then
			return "Change to Off spec"
		elseif ( CPlootAwardedItems[CPlootRuntime.FoundItemId]["RollType"] == "OffSpec" ) then
			return "Change to Main spec"
		end
	end
	return "Unkown Roll type"
end

--------------------------------------------------------
----            Find the ML in the raid             ----
--------------------------------------------------------
function CPloot:GetML()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetML() function called") end
	local ML
	for i=1, GetNumGroupMembers() do
		local RaidName, _, _, _, _, _, _, _, _, _, IsML = GetRaidRosterInfo(i)
		RaidName, _ = CPloot:GetRealPlayerName(RaidName)  -- New in 2.08
		if (IsML) then
			ML = RaidName
		end
	end
	return ML
end


--------------------------------------------------------
----    Find the Raid leader in the raid            ----
--------------------------------------------------------
function CPloot:GetRL()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetRL() function called") end
	local RL
	for i=1, GetNumGroupMembers() do
		local RaidName, IsRL, _, _, _, _, _, _, _, _, IsML = GetRaidRosterInfo(i)
		RaidName, _ = CPloot:GetRealPlayerName(RaidName)  -- New in 2.08
		if (IsRL == 2) then
			RL = RaidName
		end
	end
	return RL
end

--------------------------------------------------------
----     Set the Zone name in the raid session      ----
--------------------------------------------------------
function CPloot:SetZoneName()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetZoneName() function called") end
	if ( CPlootRuntime["InSync"] == true and CPloot:GetML() == UnitName("player") ) then
		local NewLocation = false
		local IsInstance, InstanceType = IsInInstance()
		local RaidInstance = ""
		if (IsInstance == true and InstanceType == "raid") then
			RaidInstance = GetZoneText()
		else
			RaidInstance = "none"
		end

		if not (RaidInstance == "none") then
			if (CPlootRaidRoster["Location"] == "none" or CPlootRaidRoster["Location"] == "" or CPlootRaidRoster["Location"] == nil) then
				CPlootRaidRoster["Location"] = RaidInstance
				NewLocation = true
			else
				if (string.match(CPlootRaidRoster["Location"], RaidInstance) == nil) then
					CPlootRaidRoster["Location"] = CPlootRaidRoster["Location"] .. " and " .. RaidInstance
					NewLocation = true
				end
			end
		end
	end

	-- Make sure RaidRoster["Raiders"] are updated if the raid is started and no group changes happens
	-- but only if we have an active raid.
	if ( CPlootRuntime["InSync"] == true ) then
		CPloot:StoreCPlootRaidRoster()
	end
end


--------------------------------------------------------
----       Setup a raid based on stored data        ----
--------------------------------------------------------
-- TODO
function CPloot:RaidSetup(Remote)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:RaidSetup(Remote) function called") end
	local IsML
	local MLPresent
	local RL = CPloot:GetRL()

	if ( ( UnitInRaid("player") and UnitName("player") == RL ) or CPlootRuntime["Debug"]["BypassRaid"] ) then	-- Am I in a raid?

		-- Find out if the set ML is in the raid.
		for i=1, GetNumGroupMembers() do
			local RaidName = GetRaidRosterInfo(i)
			RaidName, _ = CPloot:GetRealPlayerName(RaidName)  -- New in 2.08
			if (RaidName == CPloot_ConfigDb["MasterLooter"]) then
				MLPresent = RaidName
			end
		end


		if ( UnitName("player") == RL ) then	-- Am I raid leader?

			CPloot:ClearWinnerList()
			CPloot:GenerateCPlootWonList()
			local LootMethod = GetLootMethod()
			if ( MLPresent ) then	-- Do I have a Master looter set.
				if (LootMethod == "master") then
					SetLootMethod("master", CPloot_ConfigDb["MasterLooter"], 1)
					PromoteToAssistant(MLPresent)
				else
					SetLootMethod("master", CPloot_ConfigDb["MasterLooter"])
					PromoteToAssistant(MLPresent)
				end

			else	-- We do not have a Master Looter set who is in the raid
				if (LootMethod == "master") then
					SetLootMethod("master", UnitName("player"), 1 )
				else
					SetLootMethod("master", UnitName("player") )
				end
				CPloot:Print("WARNING: No MasterLooter found, You're it!")
			end

			CPlootRuntime["LootThresholdTimer"] = CPloot:ScheduleTimer("SetRestOfRaidUp", 1, "SetLootThreshold")
--			CPlootRuntime["RaidDifficultyTimer"] = CPloot:ScheduleTimer("SetRestOfRaidUp", 3, "SetRaidDifficulty")
			CPlootRuntime["MLCheckTimer"] = CPloot:ScheduleTimer("SetRestOfRaidUp", 2, "IsML")

		end

		CPloot:CreateAllAccounts() -- Create the table with alt and mains
	
	else
		-- CPloot:Print("You're not in a raid, or you are not the raid leader")
	end
end


--------------------------------------------------------
----  Set LootMethod and treshold when timer hits   ----
----  Timer is set from CPloot:Setup()             ----
--------------------------------------------------------
function CPloot:SetRestOfRaidUp(Type)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetRestOfRaidUp(Type) function called") end
	if (Type == "SetLootThreshold") then
		SetLootThreshold(CPloot_ConfigDb["RaidLootQuality"])	-- 3 = 10 player, 4 = 25 player, 5 = 10 player heroic, 6 = 25 player heroic. 
		CPlootRuntime["LootThresholdTimer"] = nil

	elseif (Type == "SetRaidDifficulty") then
	  --[[ Raid difficulty AI is disabled
		-- If AI is true then figure out how many we are and set raid instance.
		local Selection = ""
		
		-- If It should not change the raid selection
		if (CPloot_ConfigDb["RaidDifficulty"] == 99) then  -- New 2.08
			return
		end
		
		if (CPloot_ConfigDb["RaidDifficultyAI"] == true) then
			if ( GetNumGroupMembers() < 11 and not CPloot_ConfigDb["RaidDiffucltyHeroic"] ) then
				Selection = 3	-- Normal 10 man
			elseif (GetNumGroupMembers() < 11 and CPloot_ConfigDb["RaidDiffucltyHeroic"] ) then
				Selection = 5	-- Heroic 10 man
			elseif (GetNumGroupMembers() > 10 and not CPloot_ConfigDb["RaidDiffucltyHeroic"] ) then
				Selection = 4	-- Normal 25 man
			elseif (GetNumGroupMembers() > 10 and CPloot_ConfigDb["RaidDiffucltyHeroic"]) then
				Selection = 6	-- Heroic 25 man
			end
		else
			-- AI is not enabled set what the user requests
			Selection = CPloot_ConfigDb["RaidDifficulty"]
		end

		-- If the current raid mode does not match then change it.
		if ( Selection ~= GetRaidDifficultyID() ) then
			SetRaidDifficultyID(Selection)
		end
		
		]]
		CPlootRuntime["RaidDifficultyTimer"] = nil


	elseif (Type == "IsML") then
		-- Build our Raid session info if I pressed the setup button
		if ( not CPlootRaidRoster["RaidsessionId"] and CPlootRuntime["LocalSetupButtonPressed"] == true and CPlootRuntime["InSync"] == false ) then
			local build, _, tocversion = select(2, GetBuildInfo())
			local Foo, bar, GUID = strsplit("-", UnitGUID("player"))
			CPlootRaidRoster["RaidsessionId"] = GUID .. tocversion .. build .. tostring((GetTime() * 1000))
			CPlootRaidRoster["MasterLooter"] = UnitName("player")
			CPlootRaidRoster["Date"] = date("%Y/%m/%d")
			CPlootRaidRoster["Version"] = CPlootRuntime["VersionMajor"] .. "." .. CPlootRuntime["VersionMinor"]
			CPlootRaidRoster["Raiders"] = {}
			CPlootRaidRoster["RaidMode"] = CPloot_ConfigDb["OfficialMode"]
			CPlootRaidRoster["Realm"] = GetRealmName()
			CPlootRaidRoster["Guild"] = GetGuildInfo("player")
			CPloot:SetRaidNuker()

			-- Start storing attendance and broadcast to others they should do the same.
			CPlootRuntime["InSync"] = true
			CPloot:SetZoneName() -- Check if the player has already entered an instance, and get the name.
		end
		-- Always clear the button pressed mark
		CPlootRuntime["LocalSetupButtonPressed"] = false
	end
end


--------------------------------------------------------
----   Set the raid Nuker based on Guild Roster     ----
--------------------------------------------------------
function CPloot:SetRaidNuker()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetRaidNuker() function called") end
	local InEnchanting = false  -- keep track of profession group
	local SkillName = "Enchanting"  -- profession we are looking for
	local NukerName = UnitName("player")
	local NukerSkill = 1

	for index=1, GetNumGuildTradeSkill(), 1 do
		local skillID, isCollapsed, iconTexture, headerName, _, numOnline, numPlayers, playerName, playerNameWithRealm, class, online, zone, skill, classFileName, isMobile = GetGuildTradeSkillInfo(index)
		
		if (headerName) then -- Expand headers to be able to read users
			_G.ExpandGuildTradeSkillHeader(skillID)
		end

		if (headerName == SkillName) then
			InEnchanting = true
		end
   
		if (headerName ~= nil and headerName ~= SkillName) then
			InEnchanting = false
		end
   
		if (InEnchanting == true and playerName ~= nil) then
			for i=1, GetNumGroupMembers() do
				local RaidName, _, _, _, _, _, _, _, _, _, _ = GetRaidRosterInfo(i)
				RaidName, _ = CPloot:GetRealPlayerName(RaidName)  -- New in 2.08
				if (RaidName == playerName) then
					if (skill > NukerSkill) then
						NukerName = playerName
						NukerSkill = skill
					end
				end
			end
		end
	end

	CPloot:SetNuker(Input, NukerName)
end

--------------------------------------------------------
----   Return the text version of the addon mode    ----
--------------------------------------------------------
function CPloot:GetAddonModeText()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetAddonModeText() function called") end
	if (CPloot_ConfigDb["OfficialMode"]) then
		return "Official"
	else
		return "Unofficial"
	end
end

--------------------------------------------------------
----          Print the version number              ----
--------------------------------------------------------
function CPloot:OpenConfig()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:OpenConfig() function called") end
	CPloot:GetGuildRanks()
	InterfaceOptionsFrame_OpenToCategory("CPloot")
	if ( CPlootRuntime.FirstConfigFrameCall ) then
		-- Call InterfaceOptionsFrame_OpenToCategory function again as it does not react to first call (Blizzard bug)
		InterfaceOptionsFrame_OpenToCategory("CPloot")
		CPlootRuntime.FirstConfigFrameCall = nil -- Set to nil so double call is not performed again
	end
end

--------------------------------------------------------
----          Print the version number              ----
--------------------------------------------------------
function CPloot:GetVersion()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetVersion() function called") end
	local Version = CPlootRuntime["VersionMajor"] .. "." .. CPlootRuntime["VersionMinor"]
	-- CPloot:Print("Version: " .. Version)
	return Version
end

--------------------------------------------------------
----  Any thing we need to do when we login or rl   ----
--------------------------------------------------------
function CPloot:OnEnable()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:OnEnable() function called") end
	CPlootFrames:OnEnable()
end

--------------------------------------------------------
----         Enables or disables the addon          ----
--------------------------------------------------------
function CPloot:EnableDisable()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:EnableDisable() function called") end
	if (CPloot_ConfigDb["Enabled"]) then
		CPloot_ConfigDb["Enabled"] = false
		CPloot:Print("Addon Disabled")
	else
		CPloot_ConfigDb["Enabled"] = true
		CPloot:Print("Addon Enabled")
		CPloot:RaidGroupChanged()
	end
end

--------------------------------------------------------
----             Set the Loot Quality               ----
--------------------------------------------------------
-- Remove after testing
function CPloot:SetLootQuality(Input, Quality)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetLootQuality(Input, Quality) function called") end
	-- Input is from commandline
	-- Quality is from the menu

	if (Input) then
		Quality = string.sub(Input, -1,-1)
	end

	Quality = tonumber(Quality)
	CPlootRuntime["Debug"]["LootQuality"] = Quality
end

--------------------------------------------------------
----      Check to see if this is a new raid        ----
--------------------------------------------------------
-- TODO No sync and new feature to check if we are continuing an old raid.
function CPloot:RaidGroupChanged(Event, ...)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:RaidGroupChanged(Event, ...) function called") end

	if ( (UnitInRaid("player") and CPloot_ConfigDb["Enabled"]) or (CPlootRuntime["Debug"]["BypassRaid"])  ) then

		-- Fix if only one is running the addon, so the list at least have the players name.
		CPlootRuntime["MLCandidates"][UnitName("player")] = UnitName("player")

		
		if not ( CPlootRuntime["IsInRaid"] ) then -- This is a new raid
			CPlootRuntime["IsInRaid"] = 1
--			CPloot:ClearWinnerList()
		end

		-- Store the data if we have an active raid
		if ( CPlootRuntime["InSync"] == true ) then
			CPloot:StoreCPlootRaidRoster()
		end

	else -- Left raid group
		CPlootRuntime["IsInRaid"] = nil
		-- Need to stop collecting CPlootRaidRoster
		CPlootRuntime["InSync"] = false

	end

end

--------------------------------------------------------
----       Keep track of who is in the raid         ----
--------------------------------------------------------
function CPloot:StoreCPlootRaidRoster()
-- TODO Add gathering of guild rank	
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:StoreCPlootRaidRoster() function called") end
	for ri = 1, GetNumGroupMembers() do
		local rname = GetRaidRosterInfo(ri)
		rname, _ = CPloot:GetRealPlayerName(rname) -- New in 2.08
		CPloot:CreateAccounts(rname)
		local newrname = CPloot:GetMainName(rname)
		for gi = 1, GetNumGuildMembers(true) do
			local gname, _, Rank = GetGuildRosterInfo(gi)
			gname, _ = CPloot:GetRealPlayerName(gname)  -- New in 2.08
			if (newrname == gname) then
				CPlootRaidRoster["Raiders"][gname] = Rank
			end
		end
	end
end

--------------------------------------------------------
----  Change the mode of the addon Official or      ----
----  Unofficial                                    ----
--------------------------------------------------------
-- TODO Change functions around it to make sure it does not change Guild roster data if in unofficial.
function CPloot:ChangeMode()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:ChangeMode() function called") end
	local CPlootResultFrame = CPlootFrames:GetFrame("CPlootResultFrame")
	if (CPlootRuntime["RollStatus"] == "Running" or CPlootResultFrame:IsVisible() ) then
		CPloot:Print("It's not permitted to change mode in the middle of a roll or if the roll window is shown")
		return
	end

	if (CPloot_ConfigDb["OfficialMode"]) then
		CPloot_ConfigDb["OfficialMode"] = false
		CPloot:Print("Addon is now in Unofficial mode")
	else
		CPloot_ConfigDb["OfficialMode"] = true
		CPloot:Print("Addon is now in Official mode")
	end
	CPlootFrames:UpdateStatusFrame()
end

-------------------------------------------------------
----    Start roll by linking in chat (Debug)      ----
-------------------------------------------------------
-- TODO Currently not working.
function CPloot:ManualLootStart(Input)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:ManualLootStart() function called") end
	if (not Input) then
		return
	end

	local Frame = CPlootFrames:GetFrame("CPlootFrame")
	if ( Frame:IsVisible() ) then
		CPloot:Print("Can't start a roll when your already looting")
		return
	end

	local ItemLink = string.sub(Input, 7, -1)
	local TooltipInfo = CPloot:CheckItem(ItemLink)
	local ItemName = string.match(ItemLink, ".+|h%[(.+)%]|h.+")
	local _, _, ItemRarity, ItemLevel, _, ItemType, ItemSubType, _, _, _ = GetItemInfo(ItemLink)

	local LootList = "Normal"

	for Index=1, #CPlootLists, 1 do
		ItemLevel = tostring(ItemLevel)
		ItemRarity = tostring(ItemRarity)
		if (CPlootLists[Index]["Min"] <= ItemLevel and CPlootLists[Index]["Max"] >= ItemLevel and ItemType == "Miscellaneous" and ItemSubType == "Junk" and ItemRarity == "4" ) then
			LootList = CPlootLists[Index]["List"]
		end
	end

	local LootInfo = {
		["ItemName"] = ItemName,
		["ItemLink"] = ItemLink,
		["ItemType"] = ItemType,
		["ItemSubType"] = ItemSubType,
		["BindType"] = TooltipInfo["BindType"],
		["ArmorType"] = TooltipInfo["ArmorType"],
		["EquipSlot"] = TooltipInfo["EquipSlot"],
		["ClassLimit"] = TooltipInfo["ClassLimit"],
		["LootList"] = LootList,
		["LootSlotId"] = 1,
		["ButtonId"] = 1,
	}
	table.insert(CPlootRuntime["Loot"], LootInfo)
	CPlootFrames:CreateLootRow(LootInfo)

end

-------------------------------------------------------
---- Loot window has been opened gather data       ----
-------------------------------------------------------
function CPloot:GatherLootData()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GatherLootData() function called") end
	if ( (UnitInRaid("player") and CPloot_ConfigDb["Enabled"] and CPlootRuntime["InSync"] == true and CPloot:GetML() == UnitName("player") ) or (CPlootRuntime["Debug"]["BypassRaid"]) ) then
		-- Store what boss we killed
		local LootTarget = nil
		local LootTargetGuid = nil
		if (UnitName("target")) then -- Make sure the window did not close to fast to get the data.
			LootTarget = UnitName("target")
			LootTargetGuid = tonumber((UnitGUID("target")):sub(-12, -9), 16) -- npc id
		end
		-- Store the loot data
		local LootInfo = {}
		local FoundAutoLoot = {}
		ButtonId = 0
		for i=1, GetNumLootItems() do
			if (GetLootSlotType(i) == 1) then
				local Icon, ItemName, Quantity, Quality = GetLootSlotInfo(i)
				local ItemLink = GetLootSlotLink(i)
				local TooltipInfo = CPloot:CheckItem(ItemLink)
--				local _, _, ItemRarity, ItemLevel, _, ItemType, ItemSubType, _, _, _ = GetItemInfo(ItemLink)
				local ItemName, ItemLink, ItemRarity, ItemLevel, ItemMinLevel, ItemType, ItemSubType, ItemStackCount, ItemEquipLoc, ItemTexture, ItemSellPrice = GetItemInfo(ItemLink)
				
				-- Rewrite to make use of the new split format.
				local SplitItemLink = {}
				SplitItemLink = CPloot:Split(":",ItemLink)
				local Tooltip = SplitItemLink[2]
				
				local EquipSlot -- Find the equipment slot so we can match it to a list / ladder.
				if ( not ItemEquipLoc) then
					EquipSlot = "None"
				else
					EquipSlot = CPloot:Split("_", ItemEquipLoc, 2)
				end

				local LootList = "Armor" -- Armor is default list / ladder.
				for Index=1, #CPlootLists, 1 do
					ItemLevel = tostring(ItemLevel)
					ItemRarity = tostring(ItemRarity)
					-- Check for Tier item.
					if (CPlootLists[Index]["Min"] <= ItemLevel and CPlootLists[Index]["Max"] >= ItemLevel and ItemType == "Miscellaneous" and ItemSubType == "Junk" and ItemRarity == "4" ) then
						LootList = CPlootLists[Index]["List"]
					elseif (ItemType == "Miscellaneous" and ItemSubType == "Mount") then
						LootList = "Mount"
					-- Check for Equipment slot.
					elseif (EquipSlot ~= "None") then
						for SlotIndex, Slot in ipairs(CPlootLists[Index]["EquipSlot"]) do
							if (Slot == EquipSlot) then
								LootList = CPlootLists[Index]["List"]
							end
						end
					end				
				end

				if (Quality >= CPlootRuntime["Debug"]["LootQuality"]) then
					ButtonId = ButtonId + 1
					LootInfo = {
						["ItemName"] = ItemName,
						["ItemLink"] = ItemLink,
						["Tooltip"] = Tooltip,
						["LootSlotId"] = i,
						["ButtonId"] = ButtonId,
						["ItemType"] = ItemType,
						["BindType"] = TooltipInfo["BindType"],
						["ArmorType"] = TooltipInfo["ArmorType"],
						["EquipSlot"] = EquipSlot,
						["ClassLimit"] = TooltipInfo["ClassLimit"],
						["LootList"] = LootList,
						["ItemSubType"] = ItemSubType,
					}
					table.insert(CPlootRuntime["Loot"], LootInfo)
					CPlootFrames:CreateLootRow(LootInfo)
				end
			elseif (GetLootSlotType(i) == 2) then  -- Autoloot money
				LootSlot(i)
			end
		end
		CPlootRuntime["AutoLootTimer"] = CPloot:ScheduleTimer("AutoLoot", 4, FoundAutoLoot)
	end
end

-------------------------------------------------------
---- 	       	   Delayed Autoloot                ----
-------------------------------------------------------
function CPloot:AutoLoot(FoundAutoLoot)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:AutoLoot(FoundAutoLoot) function called") end
	CPlootRuntime["AutoLootTimer"] = nil

	for Index = 1, #FoundAutoLoot, 1 do
		LootSlot(FoundAutoLoot[Index]["Slot"])
	end
end

-------------------------------------------------------
---- 			Read an items tooltip              ----
-------------------------------------------------------
function CPloot:CheckItem(ItemLink,Pattern)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CheckItem(ItemLink, Pattern) function called") end
	CPlootTooltip = CPlootFrames:GetFrame("CPlootTooltip")
	CPlootTooltip:SetOwner( WorldFrame, "ANCHOR_NONE" );
	TooltipInfo = {}	-- DEBUG Should be local
	if (ItemLink) then
		CPlootTooltip:SetHyperlink(ItemLink)

		local EquipSlotArray = { "Head", "Neck", "Shoulder", "Back", "Chest", "Wrist", "Hands", "Waist", "Legs", "Feet", "Finger", "Trinket", "Main Hand", "Off Hand", "One-Hand", "Two-Hand", "Thrown", "Ranged", "Totem", "Relic", "Idol", "Sigil" }
		local ArmorTypeArray = { "Cloth", "Leather", "Mail", "Plate" }


		for i = 1, CPlootTooltip:NumLines(), 1 do
			-- LEFT SIDE
			local Line = _G["CPlootTooltipTextLeft" .. i]:GetText()
			if ( i == 1) then
				TooltipInfo["Name"] = Line
			elseif ( Line and string.match(Line, "Binds when picked up") ) then
				TooltipInfo["BindType"] = "BoP"
			elseif (Line and string.match(Line, "Binds when equipped") ) then
				TooltipInfo["BindType"] = "BoE"
			elseif (Line and string.match(Line, "^Classes:") ) then
				TooltipInfo["ClassLimit"] = string.match(Line, "^Classes: (.*)$")
			end

			for i = 1, #EquipSlotArray, 1 do	-- Find the equip slot
				if (Line and string.match(Line, "^" .. EquipSlotArray[i] .. "$") ) then
					TooltipInfo["EquipSlot"] = Line
				end
			end

			-- RIGHT SIDE
			local Line = _G["CPlootTooltipTextRight" .. i]:GetText()
			for i = 1, #ArmorTypeArray, 1 do		-- Find the armor type
				if (Line and string.match(Line, "^" .. ArmorTypeArray[i] .. "$") ) then
					TooltipInfo["ArmorType"] = Line
				end
			end

		end
	end
	return TooltipInfo
end

--------------------------------------------------------
----   Called when the Blizz loot frame is closed    ---
--------------------------------------------------------
function CPloot:CloseLootFrame()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CloseLootFrame() function called") end
	if (CPlootRuntime["AutoLootTimer"] ) then
		CPloot:CancelTimer(CPlootRuntime["AutoLootTimer"])
		CPlootRuntime["AutoLootTimer"] = nil
	end

	CPlootRuntime["Loot"] = {}
	local LootFrame = CPlootFrames:GetFrame("CPlootFrame")
	local ResultFrame = CPlootFrames:GetFrame("CPlootResultFrame")
	CPlootRuntime["RollStatus"] = "Stopped"
	CPlootCurrentRolls = {}
	LootFrame:Hide()
	ResultFrame:Hide()
	CPlootRuntime["RollLoot"] = {}
	CPlootRuntime["RollType"] = nil
	CPlootFrames:CleanupCPlootFrame()
	CPlootFrames:CleanupResultFrame()
end

--------------------------------------------------------
----   Called when the Result window is closed      ----
--------------------------------------------------------
function CPloot:CloseResultFrame()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CloseResultFrame() function called") end
	local ResultFrame = CPlootFrames:GetFrame("CPlootResultFrame")
	ResultFrame:Hide()
	CPlootFrames:CleanupResultFrame()
end

--------------------------------------------------------
----          Return a players guild rank            ---
--------------------------------------------------------
function CPloot:GetCharacterRank(Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetCharacterRank(Name) function called") end
	if (CPloot_ConfigDb["OfficialMode"]) then
		for i=1, GetNumGuildMembers(true), 1 do 
			local RosterName, Rank, RankIndex = GetGuildRosterInfo(i)
			RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
			if (RosterName == Name and CPloot_ConfigDb["RaiderRanks"][RankIndex] == true) then
				return 1
			elseif (RosterName == Name and CPloot_ConfigDb["RaiderRanks"][RankIndex] == false ) then
				return 2
			end
		end
		return 3 -- This is not a guild member
	else
		return 1 -- Off-raid, so fake all to raiders
	end
end

--------------------------------------------------------
----   Announces roll start and sets state          ----
--------------------------------------------------------
function CPloot:StartRolls(this)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:StartRolls(this) function called") end

	CPlootPointsLookup = CPlootPoints:GetRaidPoints()

	CPloot:Print("CPlootPointsLookup table with player points:")
	CPloot:DumpArray(CPlootPointsLookup)

	CPlootFrames:CleanupResultFrame()
	CPlootCurrentRolls = {}
	CPlootRuntime["RollStatus"] = "Running"
	CPlootRuntime["RollLoot"] = this["LootInfo"]
	
	CPloot:SetNukeButton()

	-- Find out what type of roll it is.
	if (string.find(this:GetName(), "CPlootMainSpec%d+")) then
		CPlootRuntime["RollType"] = "MainSpec"
		SendChatMessage("Main Spec roll for " .. this["LootInfo"]["ItemLink"], "RAID_WARNING")
	elseif (string.find(this:GetName(), "CPlootOffSpec%d+")) then
		CPlootRuntime["RollType"] = "OffSpec"
		SendChatMessage("Off Spec roll for " .. this["LootInfo"]["ItemLink"], "RAID_WARNING")
	end

	-- update the Result frame's roll type frame
	local ResultFrameMode = CPlootFrames:GetFrame("CPlootResultFrameRollType")
	ResultFrameMode.Text:SetText(CPlootRuntime["RollType"] .. "\n\n" .. this["LootInfo"]["ItemLink"])
	ResultFrameMode:SetWidth( CPlootFrames:GetFrame("CPlootResultFrame"):GetWidth() - 60)
	ResultFrameMode:SetHeight(ResultFrameMode.Text:GetHeight() + 12) 

	local ResultFrame = CPlootFrames:GetFrame("CPlootResultFrame")
	ResultFrame:Show()
end

-------------------------------------------------------------------------------------------
----   Register incoming rolls (use loot points in official and won items in unofficial ---
-------------------------------------------------------------------------------------------
function CPloot:IncomingRolls(Event, String)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:IncomingRolls(Event, String) function called") end

	if (CPlootRuntime["RollStatus"] == "Running") then  -- Do we have a roll going?
		local Name, Roll, Controll = string.match(String, "(.*) rolls (%d+) %((1%-100)%)")
		local RejectedRoller = nil

		CPloot:Debug("MasterLoot",Roll)

		if (Name) then
			for i=1, #CPlootCurrentRolls do -- Is this a double roll if so complain and abort
				if (CPlootCurrentRolls[i]["Name"] == Name) then
					RejectedRoller = Name
				end
			end

			if (RejectedRoller) then
				CPloot:Print("Rejected double roll from " .. RejectedRoller)
				return
			end

			-- ArmorTypeMatch 
			-- 9 = No match
			-- 8 = Match
			local ArmorTypeMatch = "9" 
			for i = 1, GetNumGroupMembers() do
				local RosterName, _, _, _, Class, _, _, _, _, _, _ = GetRaidRosterInfo(i)
				RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
				if (RosterName == Name) then
					if ( CPlootRuntime.RollLoot.ArmorType ) then
						if ( ( Class == "Mage" or Class == "Warlock" or Class == "Priest" ) and CPlootRuntime.RollLoot.ArmorType == "Cloth" ) then
							ArmorTypeMatch = "8"
						elseif ( ( Class == "Druid" or Class == "Rogue"  or Class == "Monk" ) and CPlootRuntime.RollLoot.ArmorType == "Leather" ) then
							ArmorTypeMatch = "8"
						elseif ( ( Class == "Shaman" or Class == "Hunter" ) and CPlootRuntime.RollLoot.ArmorType == "Mail" ) then
							ArmorTypeMatch = "8"
						elseif ( ( Class == "Warrior" or Class == "Paladin" or Class == "Death Knight" ) and CPlootRuntime.RollLoot.ArmorType == "Plate" ) then
							ArmorTypeMatch = "8"
						end
					end
				end
			end


			local InvertedRoll = tostring(string.format("%02d", 100 - Roll))
			local WinnerIndex
			local WinnerListNumber
			-- Use loot points if official mode
			if (CPloot_ConfigDb["OfficialMode"]) then
				local PointsCategory = CPlootPoints:GetPointsCategory(CPlootRuntime["RollLoot"]["LootList"],CPlootRuntime["RollType"])
				CPloot:Print("PointsCategory: " .. PointsCategory)
				WinnerIndex = tostring( string.format("%04d", 9999-CPlootPointsLookup[Name][PointsCategory]))
				CPloot:Print("WinnerIndex: " .. tostring(WinnerIndex))
				WinnerListNumber = CPlootPointsLookup[Name][PointsCategory] -- Points available official
			-- Use won items if official mode
			else
				WinnerIndex = tostring( string.format("%03d", CPloot:GetWinnerIndex(Name, CPlootRuntime["RollLoot"]["LootList"]) ) )
				WinnerListNumber = tostring(CPloot:GetWinnerIndex(Name, CPlootRuntime["RollLoot"]["LootList"])) -- Won Items unofficial
			end
			Index = tostring(CPloot:GetCharacterRank(Name) .. ArmorTypeMatch .. WinnerIndex .. InvertedRoll)
			CPloot:Print("Index: " .. Index)
			
			table.insert(CPlootCurrentRolls,
			{
				Name = Name,
				Roll = Roll,
				Rank = CPloot:GetCharacterRank(Name),
				Index = tostring(Index),
				ArmorTypeMatch = ArmorTypeMatch,
				WinnerListNumber = WinnerListNumber
			})

			table.sort(CPlootCurrentRolls, CPlootRollSort)

			CPlootFrames:PopulateResultWindow(CPlootCurrentRolls)
		end
	end
end

---------------------------------------------------------
----            Roll Index sort function             ----
---------------------------------------------------------
function CPlootRollSort(RollA,RollB)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CPlootRollSort(RollA,RollB) function called") end
	if(RollA.Index < RollB.Index) then
		return RollA.Index < RollB.Index
	end
end

---------------------------------------------------------
----   	        Announce all the loot                ----
---------------------------------------------------------
function CPloot:AnnounceLoot()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:AnnounceLoot() function called") end
	SendChatMessage("We have", "RAID_WARNING")

	local ItemLinks = ""
	local Loop = 1
	for Index = 1, #CPlootRuntime["Loot"] do
		ItemLinks = ItemLinks .. " " .. CPlootRuntime["Loot"][Index]["ItemLink"]
		if (Loop == 2) then
			SendChatMessage(ItemLinks, "RAID")
			Loop = 0
			ItemLinks = ""
		end
		Loop = Loop + 1
	end
	
	if (ItemLinks) then
		SendChatMessage(ItemLinks, "RAID")
	end
end

---------------------------------------------------------
----   Get the Winner index Number by name           ----
---------------------------------------------------------
-- TODO Change to match new point system.
function CPloot:GetWinnerIndex(Name, LootList)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetWinnerIndex(Name, LootList) function called") end
	-- If it's an official raid and mainspec, or if it's off raid use winnerlist

	-- Make sure that any one that has rolled is in the lootlist with 000
	if ( not CPlootWonList[LootList][CPlootRuntime["RollType"]][Name] ) then
		CPlootWonList[LootList][CPlootRuntime["RollType"]][Name] = 000
	end
	CPloot:Print("LootList value: " .. LootList)
	CPloot:Print("RollType value: " .. CPlootRuntime["RollType"])
	CPloot:Print("Return value from GetWinnerIndex: " .. CPlootWonList[LootList][CPlootRuntime["RollType"]][Name])
	-- Find out what should be returned
	return CPlootWonList[LootList][CPlootRuntime["RollType"]][Name]


end

---------------------------------------------------------
----  Award Item to a winner                         ----
---------------------------------------------------------
-- TODO players are no longer getting a +1 when getting an item, but they are reset to 0.
function CPloot:AwardItem(Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:AwardItem(Name) function called") end
	CPloot:EndRolls()

	-- Increment a players won item number

	if (CPlootRuntime["RollLoot"]["ItemType"] ~= "Recipe") then -- Don't penalize for Recipes
		CPlootWonList[CPlootRuntime["RollLoot"]["LootList"]][CPlootRuntime["RollType"]][Name] = CPlootWonList[CPlootRuntime["RollLoot"]["LootList"]][CPlootRuntime["RollType"]][Name] + 1
	end

	CPloot:GiveItem(Name)
end

--------------------------------------------------------
----              Nuke an item                      ----
--------------------------------------------------------
-- TODO Storing nuking of an item is required to move items from nuked to a player during the raid.
function CPloot:NukeItem()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:NukeItem() function called") end

	local Name = "_nuked"
	table.insert(CPlootCurrentRolls,
	{
		Name = "_nuked",
		Roll = 999,
		Rank = 1,
		Index = 3999999,
		ArmorTypeMatch = 9,
		WinnerListNumber = 99,
	})
	
	
	if ( not CPlootWonList[CPlootRuntime["RollLoot"]["LootList"]][CPlootRuntime["RollType"]][Name] ) then
		CPlootWonList[CPlootRuntime["RollLoot"]["LootList"]][CPlootRuntime["RollType"]][Name] = 000
	end

	CPlootWonList[CPlootRuntime["RollLoot"]["LootList"]][CPlootRuntime["RollType"]][Name] = CPlootWonList[CPlootRuntime["RollLoot"]["LootList"]][CPlootRuntime["RollType"]][Name] + 1

	CPloot:StoreAwardedItem("_nuked")
	CPloot:GiveItem(CPlootRuntime["Nuker"], true)
	CPlootRuntime["SyncAwarded"] = true
end

--------------------------------------------------------
----            Give Item to Bank                   ----
--------------------------------------------------------
function CPloot:BankItem()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:BankItem() function called") end
	if (CPloot:GetML() ~= UnitName("player") ) then
		return
	end

	for i = 1, GetNumGuildMembers(), 1 do
		local RosterName, _, RankIndex = GetGuildRosterInfo(i)
		RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
		if (RankIndex == 0 or RankIndex == 1 or RankIndex == 2) then -- 0 = GM, 1 = Officers, 2 = Officers
--			for RaidIndex = 1, GetNumGroupMembers() do
			for RaidIndex = 1, 25 do
				local RaidName = GetRaidRosterInfo(RaidIndex)
				RaidName, _ = CPloot:GetRealPlayerName(RaidName)  -- New in 2.08
				if (RaidName == RosterName) then
					CPloot:GiveItem(RosterName, true)	-- True = this should not be registered as an item won
					SendChatMessage("Giving you the item for the guild bank", "WHISPER", "Common", RosterName);
					return true
				end
			end
		end
	end
	CPloot:CleanUpAfterItem()
	CPloot:Print("|cffc41f3b I did not find an Officer to hand the item to, you have to give it to some one yourself")
end

--------------------------------------------------------
----  Find the "Loot Candidate" and give out item    ----
--------------------------------------------------------
-- TODO review if it will work with the new point system.
function CPloot:GiveItem(Name, Nuking)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GiveItem(Name, Nuking) function called") end

	for Loop = 1, 4 do
		CPlootRuntime["Debug"]["MasterLootCandidates"] = {}
		CPloot:Debug("MasterLoot", "Looking for " .. Name)
		for Candidate = 1, GetNumGroupMembers() do  -- Lets Hand out the item
			table.insert(CPlootRuntime["Debug"]["MasterLootCandidates"], Candidate)
			if ( GetMasterLootCandidate(CPlootRuntime["RollLoot"]["LootSlotId"], Candidate) == Name ) then
				CPloot:Debug("MasterLoot", "Got a Match for handout " .. GetMasterLootCandidate(CPlootRuntime["RollLoot"]["LootSlotId"], Candidate) )
				GiveMasterLoot(CPlootRuntime["RollLoot"]["LootSlotId"], Candidate)
				if (Nuking) then
					SendChatMessage("Nuking " .. CPlootRuntime["RollLoot"]["ItemLink"], "RAID")
				else
					SendChatMessage("Awarded ".. CPlootRuntime["RollLoot"]["ItemLink"] .. " to " .. Name, "RAID")
					CPlootRuntime["SyncAwarded"] = true
					CPloot:StoreAwardedItem(Name)
				end
				
				CPloot:CleanUpAfterItem()
				CPloot:Debug("MasterLoot","Use /dump CPlootRuntime[\"Debug\"][\"MasterLootCandidates\"] to see the full list")
				return true
			end
		end
	end
	
	CPloot:Debug("MasterLoot","Use /CPlootloot debug dumpwinnerlist to see the full list")
	if not (Nuking) then
		SendChatMessage("Tried to hand out ".. CPlootRuntime["RollLoot"]["ItemLink"] .. " to " .. Name .. " but ML hand out failed", "RAID")
		CPlootRuntime["SyncAwarded"] = true
		CPloot:StoreAwardedItem(Name)
	else
		CPloot:Print(RED_FONT_COLOR_CODE .. "Tried to hand out ".. CPlootRuntime["RollLoot"]["ItemLink"] .. RED_FONT_COLOR_CODE .. " to " .. CPloot:GetTextColor("Name",Name) .. Name .. RED_FONT_COLOR_CODE .. " for nuking but ML hand out failed")
	end
	CPloot:CleanUpAfterItem()
end

--------------------------------------------------------
----          Store and Awarded Item                ----
--------------------------------------------------------
-- TODO Missing EquipLoc in table.
function CPloot:StoreAwardedItem(Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:StoreAwardedItem(Name) function called") end
	-- Store info of who won.
		table.insert(CPlootAwardedItems, {
			ItemName = CPlootRuntime["RollLoot"]["ItemName"],
			ItemLink = CPlootRuntime["RollLoot"]["ItemLink"],
			RollType = CPlootRuntime["RollType"],
			LootList = CPlootRuntime["RollLoot"]["LootList"],
			ItemType = CPlootRuntime["RollLoot"]["ItemType"],
			ItemSubType = CPlootRuntime["RollLoot"]["ItemSubType"],
			Winner = Name,
			Rollers = CPlootCurrentRolls,
		})
end


--------------------------------------------------------
----           Find players won items,              ----
----           and who was next in line             ----
--------------------------------------------------------
-- TODO Rewrite to match new index / point system (Helper function to move items).
function CPloot:FindItemByPlayer(Input, Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:FindItemByPlayer(Input, Name) function called") end

	if (Input) then
		-- Do some thing
	end

	Name = CPloot:FormatName(Name)
	local Found = false
	for IIndex, InfoArray in pairs(CPlootAwardedItems) do	-- Grap the indidual item arrays
		if (InfoArray["Winner"] == Name) then	-- The person has won this item.
			Found = true
			CPlootRuntime["PlayerNameItemLookup"] = Name
			for RIndex, Rollers in pairs(InfoArray["Rollers"]) do
				if (Rollers["Name"] == Name) then
					local NextInLineIndex = RIndex + 1
					if (InfoArray["Rollers"][NextInLineIndex]) then
					end
				end
			end
		end
	end

	if not (Found) then
		local NameColor = CPloot:GetTextColor("Name",Name)
		CPloot:Print(NameColor .. Name .. FONT_COLOR_CODE_CLOSE .." is not registered for any won items")
		-- Reset the Dropdowns?
	else
		CPloot:CreateLookupItemsArray()
	end
end

--------------------------------------------------------
----   Create the Move Item from list for the gui   ----
--------------------------------------------------------
function CPloot:CreateItemOwnersList()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CreateItemOwnersList() function called") end
	CPlootRuntime["ItemOwnerslist"] = {}
	for Index, Array in pairs(CPlootAwardedItems) do
		CPlootRuntime["ItemOwnerslist"][CPlootAwardedItems[Index]["Winner"]] = CPloot:GetTextColor("Name",CPlootAwardedItems[Index]["Winner"]) .. CPlootAwardedItems[Index]["Winner"]
	end
	return CPlootRuntime["ItemOwnerslist"]
end


--------------------------------------------------------
----             Create the array for the           ----
----             itemlookup dropdown menu           ----
--------------------------------------------------------
function CPloot:CreateLookupItemsArray()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CreateLookupItemsArray() function called") end
	if (CPlootRuntime["PlayerNameItemLookup"] ) then
		CPlootRuntime["FoundItems"] = {}
		local Found = false
		for IIndex, InfoArray in pairs(CPlootAwardedItems) do
			if (InfoArray["Winner"] == CPlootRuntime["PlayerNameItemLookup"] ) then
				Found = true
				CPlootRuntime["FoundItems"][IIndex] = InfoArray["ItemName"]
			end
		end
	end
		
	if (Found == false) then
		CPlootRuntime["FoundItems"] = { 
			[999] = "None",
		}
		CPlootRuntime["PlayerNameItemLookup"] = nil
	end

end

--------------------------------------------------------
----            Create the array for the            ----
----           Next in line dropdown menu           ----
--------------------------------------------------------
-- TODO Rewrite to fix indexing.
function CPloot:CreateLookupRollersByItemID(FoundItemId)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CreateLookupRollersByItemID(FoundItemId) function called") end
	local Found = false
	local RealRollers = {}
	local LastIndex = 1
	CPlootRuntime["FoundItemId"] = FoundItemId
	CPlootRuntime["FoundItemRollers"] = {}

	-- Clean out the fake ones if an item has been moved
	for AIndex, AwardedArray in pairs(CPlootAwardedItems) do
		local Winner = CPlootAwardedItems[AIndex]["Winner"]

		for RIndex, RollerArray in pairs(CPlootAwardedItems[AIndex]["Rollers"]) do
			if ( RollerArray["Roll"] == 999 and Winner ~= RollerArray["Name"] ) then
				CPlootAwardedItems[AIndex]["Rollers"][RIndex] = nil
			end
		end
	end

	if (CPlootRuntime["FoundItemId"] ~= 999 ) then
		for Index, Array in pairs(CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"]) do


			if (CPlootRuntime["PlayerNameItemLookup"] == CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][Index]["Name"] ) then -- Don't list the winner
				CPlootRuntime["FoundItemRollers"][Index] = RED_FONT_COLOR_CODE .. CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][Index]["Name"]
				RealRollers[CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][Index]["Name"]] = true
			else
				CPlootRuntime["FoundItemRollers"][Index] = GREEN_FONT_COLOR_CODE .. CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][Index]["Name"]
				RealRollers[CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][Index]["Name"]] = true
			end

			if (Found == false) then
				CPlootRuntime["ChosenItemRoller"] = 999
			end
			Found = true
			LastIndex = Index
		end

		if (CPlootRuntime.ShowNonRollers and CPlootRuntime.FoundItemId) then
			for i=1, GetNumGroupMembers() do
				local Name = GetRaidRosterInfo(i)
				Name, _ = CPloot:GetRealPlayerName(Name)  -- New in 2.08
				if not ( RealRollers[Name] ) then
					LastIndex = LastIndex + 1
					CPlootRuntime["FoundItemRollers"][LastIndex] = Name
				end
			end
			LastIndex = LastIndex + 1
			CPlootRuntime["FoundItemRollers"][LastIndex] = "_nuked"
		end
	
	else
		CPlootRuntime["FoundItemRollers"] = {
			[999] = "None",
		}
	end

	CPlootRuntime["FoundItemId"] = FoundItemId	-- Needs to be set last or it can bug the FoundItemRollers varaible.
	return CPlootRuntime["FoundItemRollers"]
end


--------------------------------------------------------
----      Move item from PlayerA to PlayerB         ----
--------------------------------------------------------
-- TODO Rewrite for new indexing.
function CPloot:MoveItem(ChosenItemRoller)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:MoveItem(ChosenItemRoller) function called") end

	if (ChosenItemRoller == 999) then return end

	if (CPloot:GetML() ~= UnitName("player") ) then
		CPloot:Print("You're not ML, only the ML can reassign items")
		return
	end

	if not ( CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][ChosenItemRoller] ) then -- Did not roll but should recieve item
		CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][ChosenItemRoller] = {
			WinnerListNumber = 99,
			Name = CPlootRuntime["FoundItemRollers"][ChosenItemRoller],
			ArmorTypeMatch = 9,
			Roll = 999,
			Index = 3999999,
			Rank = 1,
		}
	end


	CPlootRuntime.ChosenItemRoller = ChosenItemRoller
	local FromPlayerName = CPlootRuntime.PlayerNameItemLookup
	local RecievingPlayerName = CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][ChosenItemRoller]["Name"]
	local Message = "Moved " .. CPlootAwardedItems[CPlootRuntime.FoundItemId]["ItemLink"] .. " from " .. FromPlayerName
	local LootList = CPlootAwardedItems[CPlootRuntime.FoundItemId]["LootList"] 
	local RollType = CPlootAwardedItems[CPlootRuntime.FoundItemId]["RollType"]

	if (CPlootAwardedItems[CPlootRuntime.FoundItemId]["ItemType"] ~= "Recipe") then  -- Recipies are free
		-- Move won points from one player to another.
		-- Move Main Spec
		if ( RollType == "MainSpec" ) then
			Message = Message .. " as main spec to " .. RecievingPlayerName
		
			CPlootWonList[LootList][RollType][FromPlayerName] = CPlootWonList[LootList][RollType][FromPlayerName] - 1

			if (CPlootRuntime.MoveRollType == false) then	-- don't change roll type
				Message = Message .. " as main spec"

				if ( CPlootWonList[LootList][RollType][RecievingPlayerName] ) then
					CPlootWonList[LootList][RollType][RecievingPlayerName] = CPlootWonList[LootList][RollType][RecievingPlayerName] + 1
				else
					CPlootWonList[LootList][RollType][RecievingPlayerName] = 1
				end

				CPloot:Print("Moved Item to " .. CPlootRuntime["FoundItemRollers"][ChosenItemRoller] .. FONT_COLOR_CODE_CLOSE .. " as MainSpec")
			
			else	-- Change roll type give new winner Offspec instead.
				Message = Message .. " as off spec"

				if ( CPlootWonList[LootList]["OffSpec"][RecievingPlayerName] ) then
					CPlootWonList[LootList]["OffSpec"][RecievingPlayerName] = CPlootWonList[LootList]["OffSpec"][RecievingPlayerName] +1
				else
					CPlootWonList[LootList]["OffSpec"][RecievingPlayerName] = 1
				end

				CPlootAwardedItems[CPlootRuntime.FoundItemId]["RollType"] = "OffSpec"
				CPloot:Print("Moved Item to " .. CPlootRuntime["FoundItemRollers"][ChosenItemRoller] .. FONT_COLOR_CODE_CLOSE .. " as OffSpec")
			end

		-- Move Offspec
		elseif ( CPlootAwardedItems[CPlootRuntime.FoundItemId]["RollType"] == "OffSpec") then
			Message = Message .. " as off spec to " .. RecievingPlayerName
		
			CPlootWonList[LootList][RollType][FromPlayerName] = CPlootWonList[LootList][RollType][FromPlayerName] - 1	

			if (CPlootRuntime.MoveRollType == false) then	-- don't change roll type
				Message = Message .. " as off spec"

				if ( CPlootWonList[LootList][RollType][RecievingPlayerName] ) then
					CPlootWonList[LootList][RollType][RecievingPlayerName] = CPlootWonList[LootList][RollType][RecievingPlayerName] + 1
				else
					CPlootWonList[LootList][RollType][RecievingPlayerName] = 1
				end

				CPloot:Print("Moved Item to " .. CPlootRuntime["FoundItemRollers"][ChosenItemRoller] .. FONT_COLOR_CODE_CLOSE .. " as Off Spec")

			else	-- Change roll type give new winner Main spec
				Message = Message .. " as main spec"

				if ( CPlootWonList[LootList]["MainSpec"][RecievingPlayerName] ) then
					CPlootWonList[LootList]["MainSpec"][RecievingPlayerName] = CPlootWonList[LootList]["MainSpec"][RecievingPlayerName] +1
				else
					CPlootWonList[LootList]["MainSpec"][RecievingPlayerName] = 1
				end

				CPlootAwardedItems[CPlootRuntime.FoundItemId]["RollType"] = "MainSpec"
				CPloot:Print("Moved Item to " .. CPlootRuntime["FoundItemRollers"][ChosenItemRoller] .. FONT_COLOR_CODE_CLOSE .. " as Main Spec")
			end
		end
			
		-- send message to raid that the item has been moved.
		SendChatMessage(Message,"RAID")
	end

	-- Change the CPlootAwardedItems array to match
	CPlootAwardedItems[CPlootRuntime.FoundItemId]["Winner"] = CPlootAwardedItems[CPlootRuntime.FoundItemId]["Rollers"][ChosenItemRoller]["Name"]

	-- Reset CPlootRuntime Variables conserning the lookup
	CPlootRuntime["FoundItems"] = {
		[999] = "None",
	}
	CPlootRuntime["FoundItemId"] = 999
	CPlootRuntime["PlayerNameITemLookup"] = nil
	CPlootRuntime["FoundItemRollers"] = {
		[999] = "None",
	}
	CPlootRuntime["ChosenItemRoller"] = "None"
	CPlootRuntime["PlayerNameItemLookup"] = nil
	CPlootRuntime["MoveRollType"] = false
end

--------------------------------------------------------
----          Clean up after award or nuke          ----
--------------------------------------------------------
function CPloot:CleanUpAfterItem()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CleanUpAfterItem() function called") end

	CPlootFrames:CleanupResultFrame() -- Clear the PlayerResultFrames
	CPlootCurrentRolls = {} -- Don't want any old rolls to be hanging around
	local ResultFrame = CPlootFrames:GetFrame("CPlootResultFrame")
	ResultFrame:Hide()
	if not ( CPlootRuntime["RollLoot"]["ButtonId"] == 200 ) then	-- 200 is magic number for autobank items.
		local MainSpecButton = CPlootFrames:GetFrame("CPlootMainSpec" .. CPlootRuntime["RollLoot"]["ButtonId"])
		MainSpecButton:Hide()
		local OffSpecButton = CPlootFrames:GetFrame("CPlootOffSpec" .. CPlootRuntime["RollLoot"]["ButtonId"])
		OffSpecButton:Hide()
	end
	CPlootRuntime["RollStatus"] = "Stopped"
	CPlootRuntime["RollType"] = nil
	CPlootRuntime["RollLoot"] = {}

end

--------------------------------------------------------
----           Set the raid nuker                   ----
--------------------------------------------------------
function CPloot:SetNuker(Input, Nuker)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetNuker(Input, Nuker) function called") end
	-- Input is from commandline, not used any more.
	-- Nuker is from menu.

	if (Nuker == "") then
		CPlootRuntime["Nuker"] = nil
		CPloot:Print("Nuker cleared, if this was not you're intent please type the name of a player in the raid.")
		return
	end

	if (Nuker) then
		for i = 1, GetNumGroupMembers() do
			local Name = GetRaidRosterInfo(i)
			Name, _ = CPloot:GetRealPlayerName(Name)  -- New in 2.08
			if (Name == Nuker) then
				CPlootRuntime["Nuker"] = Nuker
				CPloot:Print("Nuker set to " .. CPloot:GetTextColor("Name",Nuker) .. Nuker)
				Found = true
			end
		end
	end

	if (not Found) then
		CPlootRuntime["Nuker"] = nil
		CPloot:Print("Nuker cleared, if this was not you're intent please type the name of a player in the raid.")
	end
end

--------------------------------------------------------
----     Check if the Nuke button should be shown   ----
--------------------------------------------------------
function CPloot:SetNukeButton()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:SetNukeButton() function called") end
	local NukeButton = CPlootFrames:GetFrame("CPlootNukeButton")

	if ( ( (CPlootRuntime["RollLoot"]["BindType"] and CPlootRuntime["RollLoot"]["BindType"] == "BoE") or ( CPlootRuntime["RollLoot"]["ItemType"] and CPlootRuntime["RollLoot"]["ItemType"] == "Recipe") ) and CPloot_ConfigDb["OfficialMode"]) then
		NukeButton:Show()
		NukeButton:SetText("Bank")
		NukeButton:SetScript("OnMouseUP", CPloot.BankItem)
		return true
	end

	if (CPlootRuntime["Nuker"]) then
		for i=1, GetNumGroupMembers() do
			local Name = GetRaidRosterInfo(i)
			Name, _ = CPloot:GetRealPlayerName(Name)  -- New in 2.08
			if (Name == CPlootRuntime["Nuker"]) then
				NukeButton:SetScript("OnMouseUP", CPloot.NukeItem)
				NukeButton:SetText("Nuke")
				NukeButton:Show()
				return true
			end
		end
	end
	NukeButton:Hide()
end

--------------------------------------------------------
----             End the rolling                    ----
--------------------------------------------------------
function CPloot:EndRolls()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:EndRolls() function called") end
	if (CPlootRuntime["RollStatus"] == "Running") then
		-- Stop listening to rolls
		CPlootRuntime["RollStatus"] = "Stopped"
		CPloot:Print("No more rolls accepted")
	else
		CPloot:Print("No Rolling in progress, need an ongoing roll to stop it")
	end
end

--------------------------------------------------------
----          Return CPlootRuntime                 ----
--------------------------------------------------------
function CPloot:GetRuntime()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetRuntime() function called") end
	return CPlootRuntime
end

--------------------------------------------------------
----   Ask to clear the winner list when entering   ----
----   an instance                                  ----
--------------------------------------------------------
-- TODO We can not rely on sync any more ... new way to determine / ask the user.
function CPloot:ClearWinnerList(Force, Sender)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:ClearWinnerList(Force, Sender) function called") end
	
	if (CPlootRuntime["InSync"] == true and (not Force) ) then
		CPloot:Print("You're in Sync with the Master looter, so you can't clear the data")
		return
	end

	CPloot:GenerateCPlootWonList()
	CPlootAwardedItems = {}
	CPlootAccounts = {}
	CPlootRaidRoster = {
		Raiders = {},
		Bosses = {},
	}
	CPlootRuntime["InSync"] = false
	CPlootRuntime["Nuker"] = nil
	CPloot_ConfigDb["WinnerListResetDate"] = date("%d/%m/%y %H:%M")
	local Frame = CPlootFrames:GetFrame("CPlootlootWinnerListDateFrame")
	Frame.Text:SetText(CPloot_ConfigDb["WinnerListResetDate"])
	if (Force and Sender) then -- We got a broadcast to clear session.
		CPloot:Print(Sender .. " Cleared the raid session, data is no longer collected")
	elseif (Force) then
		CPloot:Print("Winner list, nuker, attendance info, Raid session, and Awarded items has been cleared")
	end
end

--------------------------------------------------------
----   Uppercase the first letter, lower case rest  ----
--------------------------------------------------------
function CPloot:FormatName(TmpName)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:FormatName(TmpName) function called") end
	if (TmpName) then
		TmpName = string.lower(TmpName)
		local Name = string.upper(string.sub(TmpName, 1, 1)) .. string.sub(TmpName,2) -- Format the name to capitalize first character, and lowercase rest
		return Name
	end
end


--------------------------------------------------------
----         Find the mains char name               ----
--------------------------------------------------------
function CPloot:GetAccountName(Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetAccountName(Name) function called") end
	for i=1, GetNumGuildMembers(true), 1 do 
		local RosterName, _, _, _, _, _, Note = GetGuildRosterInfo(i)
		RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
		if (RosterName == Name) then -- We hold the requested character
			if ( string.upper(string.sub(Note, 1, 6)) == "ALT - " ) then
				-- This was an alt return the mains name
				return string.upper(string.sub(Note, 7, 7)) .. string.lower(string.sub(Note, 8))
			else
				-- This is a main return the original name
				return string.upper(string.sub(RosterName, 1, 1)) .. string.lower(string.sub(RosterName, 2))
			end
		end
	end
	return Name
end

--------------------------------------------------------
----           Create the main to alt link          ----
--------------------------------------------------------
-- This should be called when a new name is used eg. Incoming roll, or reasign, to make sure the main and alt is linked.
function CPloot:CreateAccounts(Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CreateAccounts(Name) function called") end
	for gi=1, GetNumGuildMembers(true), 1 do 
		local RosterName, _, _, _, _, _, Note = GetGuildRosterInfo(gi)
		RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
		if (RosterName == Name) then -- We hold the requested character
			if ( string.upper(string.sub(Note, 1, 6)) == "ALT - " ) then
				-- This was an alt return the mains name
				CPlootAccounts[Name] = string.upper(string.sub(Note, 7, 7)) .. string.lower(string.sub(Note, 8))
			end
		end
	end
end

--------------------------------------------------------
----           Create the main to alt link          ----
----              Does the entire guild             ----
--------------------------------------------------------
function CPloot:CreateAllAccounts()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:CreateAllAccounts() function called") end
	for GuildIndex=1, GetNumGuildMembers(true), 1 do
		local RosterName, _, _, _, _, _, Note = GetGuildRosterInfo(GuildIndex)
		RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
		if ( string.upper(string.sub(Note, 1, 6)) == "ALT - " ) then
			-- We have an alt find Main's name
			local SplitNote = {}
			for Peice in string.gmatch(Note, "[^ ]+") do
				table.insert(SplitNote, Peice)
			end
			local Mainname = SplitNote[3]
			for GuildCheck=1, GetNumGuildMembers(true), 1 do
				local CheckName, _, _, _, _, _, Note = GetGuildRosterInfo(GuildCheck)
				CheckName, _ = CPloot:GetRealPlayerName(CheckName)  -- New in 2.08
				if (Mainname == CheckName) then -- Only insert if the main is in the guild
					CPlootAccounts[RosterName] = Mainname
				end
			end
		end
	end
end	

--------------------------------------------------------
----        Get Main account from alt name          ----
--------------------------------------------------------
function CPloot:GetMainName(Name)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetMainName(Name) function called") end
	for Alt, Main in pairs(CPlootAccounts) do
		if ( Alt == Name ) then
			-- Found the alt return the name
			return Main
		end
	end
	-- Did not find an alt, so this must be a main return the name.
	return Name
end

--------------------------------------------------------
---- Requires LibRockConsole in order to work.      ----
---- Prints arrays / hashes / frames.               ----
--------------------------------------------------------
function CPloot:DumpFrame(Array)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:DumpFrame(Array) function called") end
   Rock("LibRockConsole-1.0"):PrintLiteral(Array)
end

--------------------------------------------------------
--- Same as LibRockConsole, but sometimes LibRock    ---
--- can't print a frame or array, and sometimes      ---
--- this one can't. So both are needed               ---
--------------------------------------------------------
function CPloot:DumpArray(Array,Ignore)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:DumpArray(Array,Ignore) function called") end
	
	local Printed = false
	if (not IsAddOnLoaded("Spew")) then
		CPloot:Print("Warning: Spew is not loaded trying DevTools")
	elseif (IsAddOnLoaded("Spew") and not Ignore) then
		Spew("",Array)
		Printed = true
	end

	if (Printed == false) then
		if (not IsAddOnLoaded("DevTools")) then
	  		CPloot:Print("Warning: DevTools is not installed, giving up")
		else
			DevTools_Dump(Array)
		end
   end
end

--------------------------------------------------------
----   Does the same as the perl Split function     ----
--------------------------------------------------------
function CPloot:Split(Delimiter, Text, number)
     local list = {}
  local pos = 1 
  -- We are missing some thing 
  if ( not (Delimiter and string.len(Delimiter) >= 1) or not (Text and string.len(Text) >= 1) ) then
	  return
  end

  if strfind("", Delimiter, 1) then -- this would result in endless loops
    error("delimiter matches empty string!")
  end
  while 1 do
    local first, last = strfind(Text, Delimiter, pos)
    if first then -- found?
      tinsert(list, strsub(Text, pos, first-1))
      pos = last+1
    else
      tinsert(list, strsub(Text, pos))
      break
    end
  end
  
  if (number) then
	return list[number]
  else
    return list
  end
end

--------------------------------------------------------
----           Color Text by using HEX              ----
----           Used inline in the text              ----
--------------------------------------------------------
function CPloot:GetTextColor(Type,Data)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:GetTextColor(Type,Data) function called") end
   local ClassColors = {
	  ["DEATH KNIGHT"] = "|cffc41f3b",
	  ["DRUID"] = "|cffff7d0a",
	  ["HUNTER"] = "|cffabd473",
	  ["MAGE"] = "|cff69ccf0",
	  ["PALADIN"] = "|cfff58cba",
	  ["PRIEST"] = "|cffffffff",
	  ["ROGUE"] = "|cfffff569",
	  ["SHAMAN"] = "|cff2459ff",
	  ["WARLOCK"] = "|cff9482c9",
	  ["WARRIOR"] = "|cffc79c6e",
	  ["MONK"] = "|cff66ffcc",
   }

   if (Type == "Name") then
	  for i=1,GetNumGroupMembers() do
		 local RosterName, _, _, _, Class, _, _, _, _, _, _ = GetRaidRosterInfo(i)
		 RosterName, _ = CPloot:GetRealPlayerName(RosterName)  -- New in 2.08
		 if (Data == RosterName) then
			local Class = string.upper(Class)
			return ClassColors[Class]
		 end
	  end
   elseif (Type == "Class") then
	  local Class = string.upper(Data)
	  return ClassColors[Class]
   end
   return RED_FONT_COLOR_CODE
end

--------------------------------------------------------
----       Toggle Raid Difficutlty AI on/off        ----
--------------------------------------------------------
function CPloot:ToggleRaidDifficultyAI()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:ToggleRaidDifficultyAI() function called") end
	if (CPloot_ConfigDb["RaidDifficultyAI"]) then
		CPloot_ConfigDb["RaidDifficultyAI"] = false
	else
		CPloot_ConfigDb["RaidDifficultyAI"] = true
	end
end

--------------------------------------------------------
----  Toggle different types of debug on off        ----
--------------------------------------------------------
function CPloot:ToggleDebug(Type)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:ToggleDebug(Type) function called") end
	if (Type == "WinnerList") then
		if (CPlootRuntime["Debug"]["WinnerList"]) then
			CPlootRuntime["Debug"]["WinnerList"] = nil
			CPloot:Print("Debug WinnerList disabled")
		else
			CPlootRuntime["Debug"]["WinnerList"] = 1
			CPloot:Print("Debug WinnerList enabled")
		end

	elseif (Type == "MasterLoot") then
		if (CPlootRuntime["Debug"]["MasterLoot"]) then
			CPlootRuntime["Debug"]["MasterLoot"] = nil
			CPloot:Print("Debug MasterLoot disabled")
		else
			CPlootRuntime["Debug"]["MasterLoot"] = 1
			CPloot:Print("Debug MasterLoot enabled")
		end

	elseif (Type == "BroadcastUpdate" ) then
		if ( CPlootRuntime["Debug"]["BroadcastUpdate"] ) then
			CPlootRuntime["Debug"]["BroadcastUpdate"] = nil
			CPloot:Print("Broadcast update debug disabled")
		else
			CPlootRuntime["Debug"]["BroadcastUpdate"] = 1
			CPloot:Print("Broadcast update debug enabled")
		end
		
	elseif (Type == "VersionCheck") then
		if ( CPlootRuntime["Debug"]["VersionCheck"] ) then
			CPlootRuntime["Debug"]["VersionCheck"] = nil
			CPloot:Print("Version check is disabled")
		else
			CPlootRuntime["Debug"]["VersionCheck"] = 1
			CPloot:Print("Version check is enabled")
		end
	elseif (Type == "DebugData" ) then
		if ( CPlootRuntime["Debug"]["DebugData"] ) then
			CPlootRuntime["Debug"]["DebugData"] = nil
			CPloot:Print("Com data debug disabled")
		else
			CPlootRuntime["Debug"]["DebugData"] = 1
			CPloot:Print("Com data debug enabled")
		end
	elseif (Type == "BypassRaid") then
		if (CPlootRuntime["Debug"]["BypassRaid"] ) then
			CPlootRuntime["Debug"]["BypassRaid"] = nil
			CPloot:Print("BypassRaid Disabled")
		else 
			CPlootRuntime["Debug"]["BypassRaid"] = 1
			CPloot:Print("BypassRaid Enabled")
		end
	end
end

--------------------------------------------------------
----          Dump the WinnerList to chat           ----
--------------------------------------------------------
function CPloot:DumpWinnerList()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:DumpWinnerList() function called") end
	CPloot:DumpArray(CPlootWonList)
end


--------------------------------------------------------
----     Dump the CPlootAwardedItems to chat         ----
--------------------------------------------------------
function CPloot:DumpCPlootAwardedItems()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:DumpCPlootAwardedItems() function called") end
	CPloot:Print("CPlootAwardedItems")
	CPloot:DumpArray(CPlootAwardedItems)
end

--------------------------------------------------------
----        Dump the CPlootRuntime to chat           ----
--------------------------------------------------------
function CPloot:DumpRuntime()
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:DumpRuntime() function called") end
	CPloot:Print("CPlootRuntime")
	CPloot:DumpArray(CPlootRuntime)
end

--------------------------------------------------------
----   Will print debug if that type is enabled     ----
--------------------------------------------------------
function CPloot:Debug(MyType, Data)
	if (CPlootRuntime["Debug"]["PrintFunctionCalls"]) then CPloot:Print("CPloot:Debug(MyType, Data) function called") end
	if ( MyType == "WinnerList" and CPlootRuntime["Debug"]["WinnerList"] ) then
		if ( type(Data) == "table" ) then
			CPloot:Print("|cfffff569" ..  "WL: table")
			CPloot:DumpArray(Data)
		else
			CPloot:Print("|cfffff569" ..  "WL: " .. Data)
		end

	elseif ( MyType == "MasterLoot" and CPlootRuntime["Debug"]["MasterLoot"] ) then
		if ( type(Data) == "table" ) then
			CPloot:Print("|cfffff569" ..  "ML: table")
			CPloot:DumpArray(Data)
		else
			CPloot:Print("|cfffff569" ..  "ML: " .. Data)
		end

	elseif ( MyType == "BroadcastUpdate" and CPlootRuntime["Debug"]["BroadcastUpdate"] ) then
		if ( type(Data) == "table" ) then
			CPloot:Print("|cfffff569" ..  "LBU: table")
			CPloot:DumpArray(Data)
		else
			CPloot:Print("|cfffff569" ..  "LBU: " .. Data)
		end

	elseif ( MyType == "VersionCheck" and CPlootRuntime["Debug"]["VersionCheck"] ) then
		if ( type(Data) == "table" ) then
			CPloot:Print("|cfffff569" ..  "VC: table")
			CPloot:DumpArray(Data)
		else
			CPloot:Print("|cfffff569" ..  "VC: " .. Data)
		end
	elseif ( MyType == "Com" and CPlootRuntime["Debug"]["DebuggerName"] ) then
		if ( type(Data) == "table" ) then
			CPloot:Print("|cfffff569" ..  "VC: table")
			CPloot:DumpArray(Data, true)
		else
			CPloot:Print("|cfffff569" ..  "VC: " .. Data)
		end

	end
end

--------------------------------------------------------
----   Returns playername, realm from a guildroster ----
--------------------------------------------------------
function CPloot:GetRealPlayerName(Name)
	if (Name and string.len(Name) >= 1)  then
		local Info = CPloot:Split("-", Name)
		if (Info) then
			return Info[1], Info[2]
		else
			return Name
		end
	end
	return nil, nil
end

